package net.risesoft.api.org;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.commons.beanutils.ConvertUtils;
import org.apache.commons.beanutils.converters.DateConverter;
import org.apache.commons.codec.binary.Base64;
import org.apache.commons.lang3.StringUtils;
import org.springframework.context.annotation.Primary;
import org.springframework.data.domain.Page;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;

import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;

import net.risesoft.entity.Y9Group;
import net.risesoft.entity.Y9OrgBase;
import net.risesoft.entity.Y9Person;
import net.risesoft.entity.Y9PersonExt;
import net.risesoft.entity.Y9Position;
import net.risesoft.manager.Y9OrgBaseManager;
import net.risesoft.model.Group;
import net.risesoft.model.OrgUnit;
import net.risesoft.model.Person;
import net.risesoft.model.PersonExt;
import net.risesoft.model.Position;
import net.risesoft.model.Role;
import net.risesoft.pojo.Y9Page;
import net.risesoft.service.org.Y9GroupService;
import net.risesoft.service.org.Y9PersonExtService;
import net.risesoft.service.org.Y9PersonService;
import net.risesoft.service.org.Y9PositionService;
import net.risesoft.util.ModelConvertUtil;
import net.risesoft.y9.Y9Context;
import net.risesoft.y9.Y9LoginUserHolder;
import net.risesoft.y9.configuration.Y9Properties;
import net.risesoft.y9public.entity.Y9FileStore;
import net.risesoft.y9public.entity.role.Y9Role;
import net.risesoft.y9public.entity.user.Y9User;
import net.risesoft.y9public.service.Y9FileStoreService;
import net.risesoft.y9public.service.role.Y9RoleService;
import net.risesoft.y9public.service.user.Y9UserService;

/**
 * 人员服务组件
 *
 * @author dingzhaojun
 * @author qinman
 * @author mengjuhua
 * @date 2022/2/10
 * @since 9.6.0
 */
@Primary
@RestController
@RequestMapping(value = "/services/rest/person", produces = MediaType.APPLICATION_JSON_VALUE)
@Slf4j
@RequiredArgsConstructor
public class PersonApiImpl implements PersonApi {

    private final Y9OrgBaseManager y9OrgBaseManager;
    private final Y9GroupService y9GroupService;
    private final Y9PersonExtService y9PersonExtService;
    private final Y9PersonService y9PersonService;
    private final Y9PositionService y9PositionService;
    private final Y9RoleService y9RoleService;
    private final Y9UserService y9UserService;
    private final Y9FileStoreService y9FileStoreService;
    private final Y9Properties y9conf;

    /**
     * 改变人员的禁用状态
     *
     * @param tenantId 租户id
     * @param personId 人员id
     * @return true:禁用成功，false:禁用失败
     * @since 9.6.0
     */
    @Override
    @GetMapping("/changeDisabled")
    public boolean changeDisabled(@RequestParam String tenantId, @RequestParam String personId) {
        if (StringUtils.isBlank(tenantId) || StringUtils.isBlank(personId)) {
            return false;
        }
        Y9LoginUserHolder.setTenantId(tenantId);
        Y9Person y9Person = y9PersonService.getById(personId);
        if (Boolean.TRUE.equals(y9Person.getDisabled())) {
            y9Person.setDisabled(false);
        } else {
            y9Person.setDisabled(true);
        }
        y9PersonService.save(y9Person);
        return true;
    }

    /**
     * 检查登录名是否存在
     *
     * @param personId 人员id
     * @param loginName 登录名
     * @return boolean 用户名是否存在
     * @since 9.6.0
     */
    @Override
    @GetMapping("/checkLoginName")
    public boolean checkLoginName(@RequestParam String personId, @RequestParam String loginName) {
        return y9PersonService.checkLoginName(loginName);
    }

    /**
     * 检查手机号码是否存在
     *
     * @param personId 人员id
     * @param mobile 电话号码
     * @return boolean 是否存在
     * @since 9.6.0
     */
    @Override
    @GetMapping("/checkMobile")
    public boolean checkMobile(@RequestParam String personId, @RequestParam String mobile) {
        Y9Person y9Person = y9PersonService.getById(personId);
        return y9UserService.checkMobile(y9Person, mobile);
    }

    /**
     * 新增人员
     *
     * @param tenantId 租户id
     * @param pjson 人员对象
     * @return Person 人员对象
     * @since 9.6.0
     */
    @Override
    @PostMapping("/createPerson")
    public Person createPerson(@RequestParam String tenantId, @RequestParam String pjson) {
        Y9LoginUserHolder.setTenantId(tenantId);
        ObjectMapper om = new ObjectMapper();
        try {
            JsonNode jn = om.readTree(pjson);
            om.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
            SimpleDateFormat myFmt2 = new SimpleDateFormat("yyyy-MM-dd");
            om.setDateFormat(myFmt2);
            Y9Person y9Person = om.readValue(jn.toString(), Y9Person.class);
            ConvertUtils.register(new DateConverter(null), java.util.Date.class);
            y9Person = y9PersonService.createPerson(y9Person, y9OrgBaseManager.getParent(y9Person.getParentId()));
            return ModelConvertUtil.convert(y9Person, Person.class);
        } catch (JsonProcessingException e) {
            LOGGER.warn(e.getMessage(), e);
            return null;
        }
    }

    /**
     * 删除人员
     *
     * @param tenantId 租户id
     * @param personId 人员id
     * @return true:删除成功，false:删除失败
     * @since 9.6.0
     */
    @Override
    @PostMapping("/deleteById")
    public boolean deleteById(@RequestParam String tenantId, @RequestParam String personId) {
        Y9LoginUserHolder.setTenantId(tenantId);
        try {
            y9PersonService.delete(personId);
            return true;
        } catch (Exception e) {
            LOGGER.warn(e.getMessage(), e);
        }
        return false;
    }

    /**
     * 根据租户id和人员id获取委办局
     *
     * @param tenantId 租户id
     * @param personId 人员id
     * @return OrgUnit 机构对象
     * @since 9.6.0
     */
    @Override
    @GetMapping("/getBureau")
    public OrgUnit getBureau(@RequestParam String tenantId, @RequestParam String personId) {
        Y9LoginUserHolder.setTenantId(tenantId);
        Y9OrgBase bureau = y9PersonService.getBureau(personId);
        return ModelConvertUtil.orgBaseToOrgUnit(bureau);
    }

    /**
     * 根据登陆名和父节点id，获取人员信息
     *
     * @param tenantId 租户id
     * @param loginName 登录名称
     * @param parentId 父节点id
     * @return Person 人员对象
     * @since 9.6.0
     */
    @Override
    @GetMapping("/getByLoginNameAndParentId")
    public Person getByLoginNameAndParentId(@RequestParam String tenantId, @RequestParam String loginName, @RequestParam String parentId) {
        Y9LoginUserHolder.setTenantId(tenantId);
        Y9Person person = y9PersonService.getByLoginNameAndParentId(loginName, parentId);
        return ModelConvertUtil.convert(person, Person.class);
    }

    /**
     * 获取人员父节点
     *
     * @param tenantId 租户id
     * @param personId 人员唯一标识
     * @return OrgUnit 机构对象
     * @since 9.6.0
     */
    @Override
    @GetMapping("/getParent")
    public OrgUnit getParent(@RequestParam String tenantId, @RequestParam String personId) {
        Y9LoginUserHolder.setTenantId(tenantId);
        Y9Person y9Person = y9PersonService.getById(personId);
        Y9OrgBase parent = y9OrgBaseManager.getParent(y9Person.getParentId());
        return ModelConvertUtil.orgBaseToOrgUnit(parent);
    }

    /**
     * 根据id获得人员对象（从缓存中查找）
     *
     * @param tenantId 租户id
     * @param personId 人员唯一标识
     * @return Person 人员对象
     * @since 9.6.0
     */
    @Override
    @GetMapping("/getPerson")
    public Person getPerson(@RequestParam String tenantId, @RequestParam String personId) {
        if (StringUtils.isNotBlank(tenantId)) {
            Y9LoginUserHolder.setTenantId(tenantId);
        }
        Y9Person y9Person = y9PersonService.findById(personId);
        return ModelConvertUtil.convert(y9Person, Person.class);
    }

    /**
     * 获得人员对象（从数据库中查找）
     *
     * @param tenantId 租户id
     * @param personId 人员id
     * @return Person 人员对象
     * @since 9.6.0
     */
    @Override
    @GetMapping("/getPersonById")
    public Person getPersonById(@RequestParam String tenantId, @RequestParam String personId) {
        if (StringUtils.isNotBlank(tenantId)) {
            Y9LoginUserHolder.setTenantId(tenantId);
        }
        Y9Person y9Person = y9PersonService.findById(personId);
        return ModelConvertUtil.convert(y9Person, Person.class);
    }

    /**
     * 根据登录名获得人员对象
     *
     * @param loginName 人员登录名
     * @return Person 人员对象
     * @since 9.6.0
     */
    @Override
    @GetMapping("/getPersonByLoginName")
    public Person getPersonByLoginName(@RequestParam String loginName) {
        List<Y9User> users = y9UserService.listByLoginName(loginName);
        if (users.isEmpty()) {
            return null;
        }
        Y9LoginUserHolder.setTenantId(users.get(0).getTenantId());
        Y9Person y9Person = y9PersonService.getPersonByLoginName(loginName);
        return ModelConvertUtil.convert(y9Person, Person.class);
    }

    /**
     * 根据登录名称和租户id，获得人员对象
     *
     * @param loginName 人员登录名
     * @param tenantId 租户id
     * @return Person 人员对象
     * @since 9.6.0
     */
    @Override
    @GetMapping("/getPersonByLoginNameAndTenantId")
    public Person getPersonByLoginNameAndTenantId(@RequestParam String loginName, @RequestParam String tenantId) {
        if (StringUtils.isNotBlank(tenantId)) {
            Y9LoginUserHolder.setTenantId(tenantId);
        }
        Y9Person y9Person = y9PersonService.getPersonByLoginName(loginName);
        return ModelConvertUtil.convert(y9Person, Person.class);
    }

    /**
     * 根据人员id，获取人员扩展信息
     *
     * @param tenantId 租户id
     * @param personId 人员id
     * @return PersonExt
     * @since 9.6.0
     */
    @Override
    @GetMapping("/getPersonExtByPersonId")
    public PersonExt getPersonExtByPersonId(@RequestParam String tenantId, @RequestParam String personId) {
        Y9LoginUserHolder.setTenantId(tenantId);
        Y9PersonExt y9PersonExt = y9PersonExtService.findByPersonId(personId);
        return ModelConvertUtil.convert(y9PersonExt, PersonExt.class);
    }

    /**
     * 获取 Base64加密之后的照片字符串
     *
     * @param tenantId 租户id
     * @param personId 人员id
     * @return String Base64加密之后的照片字符串
     * @since 9.6.0
     */
    @Override
    @GetMapping("/getPersonPhoto")
    public String getPersonPhoto(@RequestParam String tenantId, @RequestParam String personId) {
        Y9LoginUserHolder.setTenantId(tenantId);
        try {
            return y9PersonExtService.getEncodePhotoByPersonId(personId);
        } catch (Exception e) {
            LOGGER.warn(e.getMessage(), e);
            return "";
        }
    }

    /**
     * 获取全部人员
     *
     * @param tenantId 租户id
     * @return List&lt;Person&gt; 人员对象集合
     * @since 9.6.0
     */
    @Override
    @GetMapping("/listAllPersons")
    public List<Person> listAllPersons(@RequestParam String tenantId) {
        Y9LoginUserHolder.setTenantId(tenantId);
        List<Y9Person> orgPersonList = y9PersonService.list();
        Collections.sort(orgPersonList);
        List<Person> personList = new ArrayList<>();
        for (Y9Person y9Person : orgPersonList) {
            personList.add(ModelConvertUtil.convert(y9Person, Person.class));
        }
        return personList;
    }

    /**
     * 根据证件类型和证件号码，获取人员列表
     *
     * @param tenantId 租户id
     * @param idType 证件类型
     * @param idNum 证件号码
     * @return
     * @since 9.6.0
     */
    @Override
    @GetMapping("/listByIdTypeAndIdNum")
    public List<Person> listByIdTypeAndIdNum(@RequestParam String tenantId, @RequestParam String idType, @RequestParam String idNum) {
        Y9LoginUserHolder.setTenantId(tenantId);
        List<Y9PersonExt> extList = y9PersonExtService.listByIdTypeAndIdNum(idType, idNum);
        List<Person> personList = new ArrayList<>();
        if (!extList.isEmpty()) {
            for (Y9PersonExt ext : extList) {
                Y9Person y9Person = y9PersonService.getById(ext.getPersonId());
                personList.add(ModelConvertUtil.convert(y9Person, Person.class));
            }
        }
        return personList;
    }

    @Override
    @GetMapping("/listByNameLike")
    public List<Person> listByNameLike(String tenantId, String name) {
        List<Y9Person> y9PersonList = y9PersonService.listByNameLike(name);
        List<Person> personList = new ArrayList<>();
        for (Y9Person y9Person : y9PersonList) {
            personList.add(ModelConvertUtil.convert(y9Person, Person.class));
        }
        return personList;
    }

    /**
     * 获取人员所在用户组列表
     *
     * @param tenantId 租户id
     * @param personId 人员唯一标识
     * @return List<Group> 用户组对象集合
     * @since 9.6.0
     */
    @Override
    @GetMapping("/listGroups")
    public List<Group> listGroups(@RequestParam String tenantId, @RequestParam String personId) {
        Y9LoginUserHolder.setTenantId(tenantId);
        List<Y9Group> orgGroupList = y9GroupService.listByPersonId(personId);
        List<Group> groupList = new ArrayList<>();
        for (Y9Group y9Group : orgGroupList) {
            groupList.add(ModelConvertUtil.convert(y9Group, Group.class));
        }
        return groupList;
    }

    /**
     * 根据人员id，获取父节点列表
     *
     * @param tenantId 租户id
     * @param personId 人员id
     * @return List&lt;OrgUnit&gt; 父节点对象集合
     * @since 9.6.0
     */
    @Override
    @GetMapping("/listParents")
    public List<OrgUnit> listParents(@RequestParam String tenantId, @RequestParam String personId) {
        Y9LoginUserHolder.setTenantId(tenantId);
        List<String> parentIds = y9PersonService.listParentIdByPersonId(personId);
        List<OrgUnit> parentList = new ArrayList<>();
        for (String parentId : parentIds) {
            Y9OrgBase parent = y9OrgBaseManager.getOrgBase(parentId);
            parentList.add(ModelConvertUtil.orgBaseToOrgUnit(parent));
        }
        return parentList;
    }

    /**
     * 根据人员名称 名称、租户id获取人员基本信息，图像，岗位等
     *
     * @param tenantId 租户id
     * @param name 人员名称
     * @return List&lt;Map&lt;String, Object&gt;&gt;
     * @since 9.6.2
     */
    @Override
    @GetMapping("/listPersonInfoByNameLike")
    public List<Map<String, Object>> listPersonInfoByNameLike(@RequestParam String tenantId, String name) {
        Y9LoginUserHolder.setTenantId(tenantId);
        List<Y9Person> y9PersonList = y9PersonService.listByNameLike(name);
        List<Map<String, Object>> infoList = new ArrayList<>();
        if (!y9PersonList.isEmpty()) {
            for (Y9Person person : y9PersonList) {
                Map<String, Object> returnMap = new HashMap<>();
                person.setPassword(null);
                returnMap.put("person", person);
                returnMap.put("personExt", y9PersonExtService.findByPersonId(person.getId()));
                returnMap.put("avator", person.getAvator());
                returnMap.put("disabled", person.getDisabled());
                if (!Boolean.TRUE.equals(person.getDisabled())) {
                    List<Y9Position> positions = y9PositionService.listByPersonId(person.getId());
                    if (!positions.isEmpty()) {
                        StringBuilder ids = new StringBuilder();
                        StringBuilder names = new StringBuilder();
                        for (Y9Position position : positions) {
                            ids.append(position.getId() + ",");
                            names.append(position.getName() + ",");
                        }
                        String nameString = names.toString();
                        String idsString = ids.toString();
                        returnMap.put("positionNames", nameString.substring(0, nameString.lastIndexOf(",")));
                        returnMap.put("positionIds", idsString.substring(0, idsString.lastIndexOf(",")));
                    } else {
                        returnMap.put("positionNames", "暂未设置");
                    }
                }
                infoList.add(returnMap);
            }
        }
        return infoList;
    }

    /**
     * 获取人员所在岗位列表
     *
     * @param tenantId 租户id
     * @param personId 人员唯一标识
     * @return List<Position> 岗位对象集合
     * @since 9.6.0
     */
    @Override
    @GetMapping("/listPositions")
    public List<Position> listPositions(@RequestParam String tenantId, @RequestParam String personId) {
        Y9LoginUserHolder.setTenantId(tenantId);
        List<Y9Position> orgPositionList = y9PositionService.listByPersonId(personId);
        List<Position> positionList = new ArrayList<>();
        for (Y9Position y9Position : orgPositionList) {
            positionList.add(ModelConvertUtil.convert(y9Position, Position.class));
        }
        return positionList;
    }

    /**
     * 获取角色
     *
     * @param tenantId 租户id
     * @param personId 人员唯一标识
     * @return List<Role> 角色对象集合
     * @since 9.6.0
     */
    @Override
    @GetMapping("/listRoles")
    public List<Role> listRoles(@RequestParam String tenantId, @RequestParam String personId) {
        Y9LoginUserHolder.setTenantId(tenantId);
        Y9Person y9Person = y9PersonService.findById(personId);
        List<Role> roleList = new ArrayList<>();
        if (StringUtils.isNotBlank(y9Person.getRoles())) {
            String[] roles = y9Person.getRoles().split(",");
            for (String acRoleId : roles) {
                roleList.add(ModelConvertUtil.y9RoleToRole(y9RoleService.findById(acRoleId)));
            }
            return roleList;
        }
        List<Y9Role> roleNodeList = y9RoleService.listOrgUnitRelatedWithoutNegative(personId);
        for (Y9Role acRoleNode : roleNodeList) {
            roleList.add(ModelConvertUtil.y9RoleToRole(acRoleNode));
        }
        return roleList;
    }

    /**
     * 修改人员密码
     *
     * @param tenantId 租户id
     * @param personId 人员id
     * @param newPassword 新明文密码
     * @return Person 人员对象
     * @since 9.6.0
     */
    @Override
    @PostMapping("/modifyPassword")
    public Person modifyPassword(@RequestParam String tenantId, @RequestParam String personId, @RequestParam String newPassword) {
        Y9LoginUserHolder.setTenantId(tenantId);
        Y9Person y9Person = y9PersonService.modifyPassword(personId, newPassword);
        return ModelConvertUtil.convert(y9Person, Person.class);
    }

    /**
     * 模糊搜索人员分页列表（不含禁用和删除）
     *
     * @param tenantId 租户id
     * @param name 人员名称
     * @param page 页数
     * @param rows 条数
     * @return
     */
    @Override
    @GetMapping("/pageByNameLike")
    public Y9Page<Person> pageByNameLike(@RequestParam String tenantId, String name, @RequestParam int page, @RequestParam int rows) {
        Y9LoginUserHolder.setTenantId(tenantId);
        if ("null".equals(name)) {
            name = "";
        }
        Page<Y9Person> persons = y9PersonService.pageByNameLike(page, rows, name);
        List<Y9Person> content = persons.getContent();
        List<Person> personList = new ArrayList<>();
        if (!content.isEmpty()) {
            for (Y9Person orgPerson : content) {
                personList.add(ModelConvertUtil.convert(orgPerson, Person.class));
            }
        }
        return Y9Page.success(persons.getNumber(), persons.getTotalPages(), persons.getTotalElements(), personList, "操作成功");
    }

    /**
     * 获取父节点下的全部人员
     *
     * @param tenantId 租户ID
     * @param parentId 部门ID
     * @param disabled 是否禁用
     * @param page 页号
     * @param rows 条数
     * @return Y9Page<Person> 人员对象集合
     * @since 9.6.0
     */
    @Override
    @GetMapping("/pageByParentId")
    public Y9Page<Person> pageByParentId(@RequestParam String tenantId, @RequestParam String parentId, @RequestParam boolean disabled, @RequestParam int page, @RequestParam int rows) {
        Y9LoginUserHolder.setTenantId(tenantId);
        Page<Y9Person> persons = y9PersonService.pageByParentId(page, rows, parentId, disabled);
        List<Y9Person> content = persons.getContent();
        List<Person> personList = new ArrayList<>();
        if (!content.isEmpty()) {
            for (Y9Person orgPerson : content) {
                personList.add(ModelConvertUtil.convert(orgPerson, Person.class));
            }
        }
        return Y9Page.success(persons.getNumber(), persons.getTotalPages(), persons.getTotalElements(), personList, "操作成功");
    }

    /**
     * 获取父节点下的全部人员
     *
     * @param tenantId 租户ID
     * @param parentId 部门ID
     * @param disabled 是否禁用
     * @param userName 用户名称
     * @param page 页号
     * @param rows 条数
     * @return Y9Page<Person> 人员对象集合
     * @since 9.6.0
     */
    @Override
    @GetMapping("/pageByParentIdAndUserName")
    public Y9Page<Person> pageByParentIdAndUserName(@RequestParam String tenantId, @RequestParam String parentId, @RequestParam boolean disabled, @RequestParam String userName, @RequestParam int page, @RequestParam int rows) {
        Y9LoginUserHolder.setTenantId(tenantId);
        Page<Y9Person> persons = y9PersonService.pageByParentId(page, rows, parentId, disabled, userName);
        List<Y9Person> content = persons.getContent();
        List<Person> personList = new ArrayList<>();
        if (!content.isEmpty()) {
            for (Y9Person orgPerson : content) {
                personList.add(ModelConvertUtil.convert(orgPerson, Person.class));
            }
        }
        return Y9Page.success(persons.getNumber(), persons.getTotalPages(), persons.getTotalElements(), personList, "操作成功");
    }

    /**
     * 保存人员
     *
     * @param tenantId 租户id
     * @param personJson 人员对象json
     * @return Person 人员对象
     * @since 9.6.0
     */
    @Override
    @PostMapping("/savePerson")
    public Person savePerson(@RequestParam String tenantId, @RequestParam String personJson) {
        Y9LoginUserHolder.setTenantId(tenantId);
        ObjectMapper om = new ObjectMapper();
        try {
            JsonNode jn = om.readTree(personJson);
            om.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
            SimpleDateFormat myFmt2 = new SimpleDateFormat("yyyy-MM-dd");
            om.setDateFormat(myFmt2);
            Y9Person y9Person = om.readValue(jn.toString(), Y9Person.class);
            Y9PersonExt y9PersonExt = om.readValue(jn.toString(), Y9PersonExt.class);

            y9Person = y9PersonService.saveOrUpdate(y9Person, y9PersonExt, y9OrgBaseManager.getParent(y9Person.getParentId()));
            return ModelConvertUtil.convert(y9Person, Person.class);
        } catch (JsonProcessingException e) {
            LOGGER.warn(e.getMessage(), e);
            return null;
        }

    }

    /**
     * 保存人员头像
     *
     * @param tenantId 租户id
     * @param personId 人员id
     * @param avator 人员头像路径
     * @return Person 人员对象
     * @since 9.6.0
     */
    @Override
    @PostMapping("/savePersonAvator")
    public Person savePersonAvator(@RequestParam String tenantId, @RequestParam String personId, @RequestParam String avator) {
        Y9LoginUserHolder.setTenantId(tenantId);
        try {
            Y9Person y9Person = y9PersonService.getById(personId);
            y9Person.setAvator(avator);
            y9Person = y9PersonService.save(y9Person);
            return ModelConvertUtil.convert(y9Person, Person.class);
        } catch (Exception e) {
            LOGGER.warn(e.getMessage(), e);
            return null;
        }
    }

    /**
     * 保存人员头像(Base64)
     *
     * @param tenantId 租户id
     * @param personId 人员id
     * @param picnote 人员头像
     * @param fileExt 文件类型(png,jpg...)
     * @return Person 人员对象
     * @since 9.6.0
     */
    @Override
    @PostMapping("/savePersonAvatorByBase64")
    public Person savePersonAvatorByBase64(@RequestParam String tenantId, @RequestParam String personId, @RequestParam String picnote, @RequestParam String fileExt) {
        Y9LoginUserHolder.setTenantId(tenantId);
        Y9Person y9Person = y9PersonService.getById(personId);
        try {
            if (StringUtils.isNotBlank(picnote)) {
                Base64 base64 = new Base64();
                if (picnote.contains("base64,")) {
                    picnote = picnote.split("base64,")[1];
                }
                byte[] data = base64.decode(picnote);
                SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss");
                String fullPath = Y9FileStore.buildFullPath(Y9Context.getSystemName(), "avator");
                String fileNewName = y9Person.getLoginName() + "_" + sdf.format(new Date()) + "." + (StringUtils.isBlank(fileExt) ? "png" : fileExt);
                
                LOGGER.debug("******savePersonAvatorByBase64:{}", fileNewName);
                
                Y9FileStore y9FileStore = y9FileStoreService.uploadFile(data, fullPath, fileNewName);
                String url = y9conf.getCommon().getOrgBaseUrl() + "/s/" + y9FileStore.getId() + "." + y9FileStore.getFileExt();
                y9Person.setAvator(url);
                y9Person = y9PersonService.save(y9Person);
                return ModelConvertUtil.convert(y9Person, Person.class);
            }
        } catch (Exception e) {
            LOGGER.warn(e.getMessage(), e);
        }
        return null;
    }

    /**
     * 保存用户照片接口
     *
     * @param tenantId 租户id
     * @param personId 人员id
     * @param photo Base64加密之后的照片字符串
     * @return Boolean 是否保存成功
     * @since 9.6.0
     */
    @Override
    @PostMapping("/savePersonPhoto")
    public Boolean savePersonPhoto(@RequestParam String tenantId, @RequestParam String personId, @RequestParam String photo) {
        Y9LoginUserHolder.setTenantId(tenantId);
        try {
            Y9Person y9Person = y9PersonService.getById(personId);
            y9PersonExtService.savePersonPhoto(y9Person, photo);
            return true;
        } catch (Exception e) {
            LOGGER.warn(e.getMessage(), e);
            return false;
        }
    }

    /**
     * 保存人员
     *
     * @param tenantId 租户id
     * @param personJson 人员对象
     * @param personextJson 人员扩展信息对象
     * @return Person
     * @since 9.6.0
     */
    @Override
    @PostMapping("/savePersonWithExt")
    public Person savePersonWithExt(String tenantId, String personJson, String personextJson) {
        Y9LoginUserHolder.setTenantId(tenantId);
        ObjectMapper om = new ObjectMapper();
        try {
            JsonNode jn = om.readTree(personJson);
            JsonNode extjn = om.readTree(personextJson);
            om.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
            SimpleDateFormat myFmt2 = new SimpleDateFormat("yyyy-MM-dd");
            om.setDateFormat(myFmt2);
            Y9Person y9Person = om.readValue(jn.toString(), Y9Person.class);
            Y9PersonExt y9PersonExt = om.readValue(extjn.toString(), Y9PersonExt.class);

            y9Person = y9PersonService.saveOrUpdate(y9Person, y9PersonExt, y9OrgBaseManager.getParent(y9Person.getParentId()));
            return ModelConvertUtil.convert(y9Person, Person.class);
        } catch (JsonProcessingException e) {
            LOGGER.warn(e.getMessage(), e);
            return null;
        }

    }

    /**
     * 保存人员的微信id
     *
     * @param tenantId 租户id
     * @param personId 人员id
     * @param weixinId 微信id
     * @return Person 人员对象
     * @since 9.6.0
     */
    @Override
    @PostMapping("/saveWeixinId")
    public Person saveWeixinId(@RequestParam String tenantId, @RequestParam String personId, @RequestParam String weixinId) {
        Y9LoginUserHolder.setTenantId(tenantId);
        Y9Person y9Person = y9PersonService.getById(personId);
        y9Person.setWeixinId(weixinId);
        y9PersonService.save(y9Person);
        return ModelConvertUtil.convert(y9Person, Person.class);
    }

}
